<template>
    <view class="checkbox" :class="{
        selected: isChecked,
        no_selected: !isChecked,
        disabled: disabled,
    }" role="checkbox" :aria-checked="isChecked" :aria-disabled="disabled" tabindex="0" @click.stop="onToggle"
        @keyup.enter.stop.prevent="onToggle" />
</template>
<script setup lang="ts">
import { computed, ref, watch } from "vue";

interface Props {
    modelValue?: boolean; // v-model 支持
    value?: boolean; // 兼容旧用法 :value
    disabled?: boolean;
}

const props = withDefaults(defineProps<Props>(), {
    modelValue: undefined,
    value: undefined,
    disabled: false,
});

const emit = defineEmits<{
    (e: "change", status: boolean): void;
    (e: "update:modelValue", val: boolean): void;
    (e: "update:value", val: boolean): void; // 兼容 :value 的双向
}>();

// 非受控本地状态（当没有传入 modelValue 与 value 时生效）
const localChecked = ref(false);

// 受控优先级：modelValue > value > local
const isChecked = computed(() => {
    if (typeof props.modelValue === "boolean") return props.modelValue;
    if (typeof props.value === "boolean") return props.value;
    return localChecked.value;
});

// 外部 props 变化时，同步本地默认值（仅在非受控时作为初值）
watch(
    () => [props.modelValue, props.value],
    ([mv, vv]) => {
        if (typeof mv !== "boolean" && typeof vv !== "boolean") {
            // 非受控：同步一次默认值
            if (typeof vv === "boolean") localChecked.value = vv;
            else if (typeof mv === "boolean") localChecked.value = mv;
        }
    },
    { immediate: true }
);

function onToggle() {
    if (props.disabled) return;
    const next = !isChecked.value;
    // 受控场景：交由父组件更新
    emit("update:modelValue", next);
    emit("update:value", next);
    emit("change", next);
    // 非受控：本地更新
    if (
        typeof props.modelValue !== "boolean" &&
        typeof props.value !== "boolean"
    ) {
        localChecked.value = next;
    }
}
</script>
<style>
.checkbox {
    width: 32rpx;
    height: 32rpx;
    border-radius: 50%;
    background-size: 100% 100%;
}

.selected {
    background-image: url("/static/common/selected.png");
}

.no_selected {
    background-image: url("/static/common/no_selected.png");
}

.disabled {
    opacity: 0.5;
}
</style>
